<template>
  <div class="file-list">
    <!-- 文件列表头部 -->
    <div class="list-header" v-if="showHeader">
      <h3 class="list-title">
        <el-icon><Document /></el-icon>
        文件列表
        <template v-if="searchKeyword && searchKeyword.trim()">
          <el-tag type="success" size="small" effect="plain">
            找到 {{ files.length }} 个匹配（搜索："{{ searchKeyword }}"）
          </el-tag>
        </template>
        <template v-else>
          <el-tag v-if="files.length > 0" type="info" size="small">
            {{ files.length }} 个文件
          </el-tag>
        </template>
      </h3>
      
      <div class="list-actions">
        <el-button size="small" text @click="refreshList">
          <el-icon><Refresh /></el-icon>
          刷新
        </el-button>
      </div>
    </div>
    
    <!-- 文件表格 -->
    <div class="table-container" v-loading="loading">
      <el-table
        :data="pagedFiles"
        @row-click="handleRowClick"
        @sort-change="onSortChange"
        @header-dragend="onHeaderDragEnd"
        border
        stripe
        highlight-current-row
        height="100%"
        class="file-table"
      >
        <!-- 文件名列 -->
        <el-table-column prop="name" label="文件名" :width="colWidths.name" show-overflow-tooltip sortable="custom">
          <template #default="{ row }">
            <div class="file-item">
              <span class="file-icon-wrapper">
                <component :is="getFileIconComponent(row.type)" v-if="shouldUseElementPlus(row)" class="file-icon" />
                <IconFont v-else :name="getIconfontName(row)" class="file-icon" />
              </span>
              <span class="file-name" v-html="highlightKeyword(row.name, searchKeyword)"></span>
            </div>
          </template>
        </el-table-column>
        
        <!-- 路径列 -->
        <el-table-column prop="path" label="路径" :width="colWidths.path" show-overflow-tooltip sortable="custom">
          <template #default="{ row }">
            <span class="file-path" v-html="highlightKeyword(row.path, searchKeyword)"></span>
          </template>
        </el-table-column>
        
        <!-- 大小列 -->
        <el-table-column prop="size" label="大小" :width="colWidths.size" align="right" sortable="custom">
          <template #default="{ row }">{{ formatFileSize(row.size || 0) }}</template>
        </el-table-column>
        
        <!-- 修改时间列 -->
        <el-table-column prop="modified" label="修改时间" :width="colWidths.modified" sortable="custom">
          <template #default="{ row }">
            <el-tooltip :content="formatDateTimeFull(row.modified)" placement="top">
              <span>{{ formatDateTime(row.modified) }}</span>
            </el-tooltip>
          </template>
        </el-table-column>
        
        <!-- 操作列 -->
        <el-table-column prop="actions" label="操作" :width="colWidths.actions" fixed="right" align="left">
          <template #default="{ row }">
            <div class="op-actions">
              <el-tooltip content="下载" placement="top">
                <el-button size="small" type="primary" circle @click.stop="downloadFile(row)">
                  <el-icon><Download /></el-icon>
                </el-button>
              </el-tooltip>
              <el-tooltip content="预览" placement="top">
                <el-button size="small" type="success" circle @click.stop="previewFile(row)">
                  <el-icon><View /></el-icon>
                </el-button>
              </el-tooltip>
              <el-tooltip content="复制路径" placement="top">
                <el-button size="small" circle @click.stop="copyPath(row)">
                  <el-icon><CopyDocument /></el-icon>
                </el-button>
              </el-tooltip>
            </div>
          </template>
        </el-table-column>
      </el-table>
      
      <!-- 空状态 -->
      <el-empty 
        v-if="!loading && files.length === 0"
        :description="emptyDescription"
        :image-size="100"
      >
        <el-button type="primary" @click="$emit('refresh')">
          <el-icon><Refresh /></el-icon>
          {{ files.length === 0 && !searchKeyword ? '开始扫描' : '重新搜索' }}
        </el-button>
      </el-empty>
    </div>
    
    <!-- 分页组件 -->
    <div class="pagination-container" v-if="files.length > pageSize">
      <el-pagination
        v-model:current-page="currentPage"
        v-model:page-size="pageSize"
        :page-sizes="[20, 50, 100, 200]"
        :total="files.length"
        layout="total, sizes, prev, pager, next, jumper"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted, onBeforeUnmount } from 'vue'
import { 
  Document, 
  Refresh, 
  Download,
  View,
  CopyDocument,
  Grid,
  Present,
  Picture,
  VideoPlay,
  Microphone,
  Box,
  DocumentCopy
} from '@element-plus/icons-vue'
import { 
  formatDateTime, 
  highlightKeyword, 
  copyToClipboard,
  formatFileSize,
  formatDateTimeFull
} from '../utils/fileUtils'
import IconFont from './IconFont.vue'
import { fileApi } from '../api/fileApi'

// 组件接口定义
const emit = defineEmits(['row-click', 'refresh'])
// 图标来源：默认内置；iconfont 加载完自动切换
const useElementPlusIcons = ref(true)

const iconfontReadyHandler = () => {
  try {
    const hasSymbols = document.querySelector('svg symbol[id^="icon-"]')
    if (hasSymbols) {
      useElementPlusIcons.value = false
    }
  } catch (e) {
    // 保持内置图标
  }
}

onMounted(() => {
  window.addEventListener('iconfont:ready', iconfontReadyHandler)
  if (window.__ICONFONT_READY__) iconfontReadyHandler()
})

onBeforeUnmount(() => {
  window.removeEventListener('iconfont:ready', iconfontReadyHandler)
})
const props = defineProps({
  // 文件列表数据
  files: {
    type: Array,
    default: () => []
  },
  // 加载状态
  loading: {
    type: Boolean,
    default: false
  },
  // 搜索关键词（用于高亮）
  searchKeyword: {
    type: String,
    default: ''
  },
  // 是否显示头部
  showHeader: {
    type: Boolean,
    default: true
  }
})

// 响应式数据
const currentPage = ref(1)          // 当前页码
const pageSize = ref(50)            // 每页大小
const sortField = ref('')           // 排序字段: name/path/size/modified
const sortOrder = ref('')           // asc/desc

// 列宽（支持持久化）
const defaultColWidths = {
  name: 360,
  path: 380,
  size: 120,
  modified: 160,
  actions: 180
}
const colWidths = ref(loadColWidths())

// 计算属性
const pagedFiles = computed(() => {
  // 全量排序
  let data = [...props.files]
  if (sortField.value && sortOrder.value) {
    const field = sortField.value
    const order = sortOrder.value
    data.sort((a, b) => {
      const av = getSortValue(a, field)
      const bv = getSortValue(b, field)
      if (av === bv) return 0
      if (order === 'asc') return av > bv ? 1 : -1
      return av < bv ? 1 : -1
    })
  }
  const start = (currentPage.value - 1) * pageSize.value
  const end = start + pageSize.value
  return data.slice(start, end)
})

const emptyDescription = computed(() => {
  if (props.searchKeyword) {
    return '未找到匹配的文件'
  }
  return '暂无文件数据，请先进行文件扫描'
})

// 监听文件列表变化，重置分页
watch(
  () => props.files.length,
  () => {
    currentPage.value = 1
  }
)

function getSortValue(row, field) {
  switch (field) {
    case 'name':
      return (row.name || '').toLowerCase()
    case 'path':
      return (row.path || '').toLowerCase()
    case 'size':
      return Number(row.size || 0)
    case 'modified':
      return new Date(row.modified || 0).getTime() || 0
    default:
      return 0
  }
}

function onSortChange({ prop, order }) {
  // order: ascending / descending / null
  sortField.value = prop || ''
  sortOrder.value = order === 'ascending' ? 'asc' : order === 'descending' ? 'desc' : ''
  currentPage.value = 1
}

function onHeaderDragEnd(newWidth, oldWidth, column, event) {
  const prop = column.property || column.prop
  if (!prop) return
  if (colWidths.value[prop] !== undefined) {
    colWidths.value[prop] = Math.max(80, Math.round(newWidth))
    saveColWidths(colWidths.value)
  }
}

function loadColWidths() {
  try {
    const raw = localStorage.getItem('fileSearch_table_colWidths')
    if (!raw) return { ...defaultColWidths }
    const parsed = JSON.parse(raw)
    return { ...defaultColWidths, ...parsed }
  } catch (e) {
    return { ...defaultColWidths }
  }
}

function saveColWidths(widths) {
  try {
    localStorage.setItem('fileSearch_table_colWidths', JSON.stringify(widths))
  } catch (e) {
    // 忽略
  }
}

/**
 * 获取文件图标组件
 * @param {string} fileType 文件类型
 * @returns {string} 图标组件名
 */
function getFileIconComponent(fileType) {
  const iconMap = {
    document: 'Document',
    spreadsheet: 'Grid',
    presentation: 'Present',
    image: 'Picture',
    video: 'VideoPlay',
    audio: 'Microphone',
    archive: 'Box',
    code: 'DocumentCopy',
    other: 'Document'
  }
  
  return iconMap[fileType] || iconMap.other
}

/**
 * 将文件类型/扩展名映射为 iconfont 名称
 */
function getIconfontName(file) {
  const ext = (file.extension || '').toLowerCase()
  const type = file.type || 'other'
  const byExt = {
    '.pdf': 'icon-format-pdf',
    '.doc': 'icon-format-doc',
    '.docx': 'icon-format-doc',
    '.xls': 'icon-format-xlsx',
    '.xlsx': 'icon-format-xlsx',
    '.csv': 'icon-format-xlsx',
    '.ppt': 'icon-doc-fill',
    '.pptx': 'icon-doc-fill',
    '.jpg': 'icon-format-jpeg',
    '.jpeg': 'icon-format-jpeg',
    '.png': 'icon-format-png',
    '.gif': 'icon-format-gif',
    '.bmp': 'icon-format-bmp',
    '.tif': 'icon-format-tif',
    '.tiff': 'icon-format-tif',
    '.zip': 'icon-format-zip',
    '.rar': 'icon-format-zip',
    '.7z': 'icon-format-zip',
    '.txt': 'icon-format-txt',
    '.md': 'icon-format-txt',
    '.json': 'icon-code'
  }
  if (byExt[ext]) return byExt[ext]
  const byType = {
    document: 'icon-format-doc',
    spreadsheet: 'icon-format-xlsx',
    presentation: 'icon-doc-fill',
    image: 'icon-pic',
    video: 'icon-video',
    audio: 'icon-audio',
    archive: 'icon-format-zip',
    code: 'icon-code',
    other: 'icon-file'
  }
  return byType[type] || 'icon-file'
}

/**
 * 判断当前项目是否应使用内置图标
 * 1) 未启用/未加载 iconfont → 内置
 * 2) iconfont 不包含对应 symbol → 内置
 */
function shouldUseElementPlus(file) {
  if (useElementPlusIcons.value) return true
  try {
    const name = getIconfontName(file)
    const id = name.startsWith('#') ? name.slice(1) : name
    const set = window.__ICONFONT_SYMBOL_SET__
    if (set && set.size > 0) {
      return !set.has(id)
    }
    const symbol = document.getElementById(id)
    return !symbol
  } catch (e) {
    return true
  }
}

/**
 * 处理行点击
 * @param {Object} row 行数据
 */
function handleRowClick(row) {
  console.log('点击文件行:', row)
  emit('row-click', row)
}

/**
 * 下载文件
 * @param {Object} file 文件信息
 */
function downloadFile(file) {
  try {
    console.log('下载文件:', file.name)
    
    // 使用API下载文件
    fileApi.downloadFile(file.id, file.name)
    
    ElMessage.success(`正在下载文件: ${file.name}`)
  } catch (error) {
    console.error('下载文件失败:', error)
    ElMessage.error('下载文件失败: ' + error.message)
  }
}

/**
 * 预览文件
 * @param {Object} file 文件信息
 */
function previewFile(file) {
  try {
    console.log('预览文件:', file.name)
    
    // 检查文件类型是否支持预览
    const previewableTypes = ['.pdf', '.jpg', '.jpeg', '.png', '.gif', '.txt', '.md', '.json']
    const extension = file.extension.toLowerCase()
    
    if (!previewableTypes.includes(extension)) {
      ElMessage.warning(`暂不支持预览 ${extension} 格式的文件，将尝试下载`)
      downloadFile(file)
      return
    }
    
    // 使用API预览文件
    fileApi.previewFile(file.id)
    
    ElMessage.success(`正在预览文件: ${file.name}`)
  } catch (error) {
    console.error('预览文件失败:', error)
    ElMessage.error('预览文件失败: ' + error.message)
  }
}

/**
 * 复制文件路径
 * @param {Object} file 文件信息
 */
async function copyPath(file) {
  try {
    const success = await copyToClipboard(file.fullPath)
    
    if (success) {
      ElMessage.success('文件路径已复制到剪贴板')
    } else {
      ElMessage.error('复制失败，请手动复制')
    }
  } catch (error) {
    console.error('复制路径失败:', error)
    ElMessage.error('复制失败: ' + error.message)
  }
}

/**
 * 刷新列表
 */
function refreshList() {
  emit('refresh')
}

/**
 * 处理每页大小变化
 * @param {number} val 新的每页大小
 */
function handleSizeChange(val) {
  pageSize.value = val
  currentPage.value = 1
}

/**
 * 处理当前页变化
 * @param {number} val 新的当前页
 */
function handleCurrentChange(val) {
  currentPage.value = val
}

// 暴露方法给父组件
defineExpose({
  refreshList
})
</script>

<style scoped>
.file-list {
  height: 100%;
  display: flex;
  flex-direction: column;
  border: 1px solid #e4e7ed;
  border-radius: 6px;
  background-color: #fff;
}

.list-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 12px 16px;
  border-bottom: 1px solid #e4e7ed;
  background-color: #fafbfc;
}

.list-title {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: #303133;
  display: flex;
  align-items: center;
  gap: 8px;
}

.list-actions {
  display: flex;
  gap: 8px;
}

.table-container {
  flex: 1;
  overflow: auto;
  max-height: 100%;
}

.file-table {
  height: auto;
  min-height: 400px;
}

.file-table :deep(.el-table__body-wrapper) {
  max-height: 400px;
  overflow-y: auto;
}

.file-item {
  display: flex;
  align-items: center;
  gap: 8px;
}

.file-icon {
  width: 16px;
  height: 16px;
  font-size: 16px;
  flex-shrink: 0;
}

.file-name {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.file-path {
  color: #909399;
  font-size: 13px;
}

.pagination-container {
  padding: 16px;
  border-top: 1px solid #e4e7ed;
  background-color: #fafbfc;
  display: flex;
  justify-content: center;
}

.op-actions {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}

/* 高亮样式 */
.file-name :deep(mark),
.file-path :deep(mark) {
  background-color: #fff359;
  color: #303133;
  padding: 0 2px;
  border-radius: 2px;
}

/* 文件类型图标颜色 */
.file-icon-document { color: #409eff; }
.file-icon-spreadsheet { color: #67c23a; }
.file-icon-presentation { color: #e6a23c; }
.file-icon-image { color: #f56c6c; }
.file-icon-video { color: #909399; }
.file-icon-audio { color: #b88bf8; }
.file-icon-archive { color: #606266; }
.file-icon-code { color: #303133; }
.file-icon-other { color: #c0c4cc; }

/* 表格行悬停效果 */
.file-table :deep(.el-table__row:hover) {
  cursor: pointer;
}

/* 空状态样式 */
.el-empty {
  padding: 40px 20px;
}

/* 响应式设计 */
@media (max-width: 768px) {
  .list-header {
    flex-direction: column;
    gap: 12px;
    align-items: flex-start;
  }
  
  .file-table :deep(.el-table__header-wrapper) {
    overflow-x: auto;
  }
  
  .pagination-container {
    padding: 12px 8px;
  }
}
</style>